package com.jason.rxjavatest.newtest;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.jason.rxjavatest.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * @author hezhiyong
 * @create 2018-04-02 10:14
 * @desc 转换操作符
 **/
public class RxJavaNewTest003 extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = RxJavaNewTest003.class.getSimpleName();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_rxjava_new003);

        findViewById(R.id.bt_map).setOnClickListener(this);
        findViewById(R.id.bt_flatmap).setOnClickListener(this);

    }


    /**
     * map就是变换需要操作的数据内容或者结构的意思。所以其使用场景显而易见：
     * 当原始数据不能满足我们的需求，但我们却需要依赖这一原始数据去获取满足我们需求的数据时
     * ，那么就用它，准没错。
     * 另一种理解：map操作符的作用就是将一个事件转换成另一个事件
     * map操作符的特点是： 你传递一个Observable对象给他， 他返回你一个Observable对象， 但是不需要对应Observable的返回类型
     */
    private void testMap() {

        Observable.from(new String[]{"Java", "Kotlin", "golang"})
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return s.toUpperCase();
                    }
                })
                .toList()
                .map(new Func1<List<String>, List<String>>() {
                    @Override
                    public List<String> call(List<String> list) {
                        Collections.reverse(list);
                        return list;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> list) {
                        Log.e(TAG, "testmap-----list-----" + list.toString());
                    }
                });


        List<String> stringList = new ArrayList<>();
        stringList.add("aaa");
        stringList.add("bbb");
        stringList.add("ccc");
        stringList.add("ddd");

        Observable.from(stringList)
                .map(new Func1<String, String>() {

                    @Override
                    public String call(String s) {
                        return s;
                    }
                }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.e(TAG, "testmap-----stringList-----" + s.toString());
            }
        });

    }


    /**
     * flatmap把一个Observable变成多个Observable，然后把得到的多个Obervable的元素一个个的发射出去
     * flatMap()操作符的作用是将Observable发射的数据集合变换为Observables集合，然后将这些Observable发射的数据平坦化的放进一个单独的Observable，还是太抽象了。
     * 简单说就是将 一个List 或者数组中的每一条数据都 转换成一个 Observable对象
     */
    private void testFlatMap() {

        getRequestObservable("first").flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String s) {
                Log.e(TAG, "testFlatMap---first--s----->" + s); //
                return getRequestObservable("two");
            }
        }).flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String s) {
                Log.e(TAG, "testFlatMap---two--s----->" + s); //
                return getRequestObservable("three");
            }
        }).flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String s) {
                Log.e(TAG, "testFlatMap---three--s----->" + s); //
                return getRequestObservable("four");
            }
        }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, "testFlatMap-----s----->" + s); // four
                    }
                });


    }

    private Observable<String> getRequestObservable(String result) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext(result);
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io());
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_map:
                testMap();
                break;


            case R.id.bt_flatmap:
                testFlatMap();
                break;

        }
    }
}
